package com.sls.api.util;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.RandomAccessFile;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

/**
 * 使用dom4j生成xml文件
 * 
 * @author cx
 * 
 */
public class CreateXMLByDom4j {

	private static Logger log = Logger.getLogger(CreateXMLByDom4j.class);
	private static String REGEX = "\\.";
	private static String UTF8 = "UTF-8";

	/**
	 * 生成对账xml文件
	 * 
	 * @param filePath
	 * @param userId
	 * @param ptOrderNo
	 * @param gameAccount
	 * @param supOrderCreateTime
	 * @param goodsId
	 * @param goodsName
	 * @param status
	 * @param amount
	 */
	public static void createCheckAccountFile(String filePath, String userNo,
			String ptOrderNo, String gameAccount, String goodsId,
			String unitPrice, String buyNum, String status, String totalPrice,
			String date) {
		String realPath = PropertiesUtil.getValue("bill.project.path");
		String folderName = PropertiesUtil.getValue("bill.folder.name");
		List<String> fileNames = readFiles(realPath + File.separator
				+ folderName + File.separator + date);
		boolean flag = userNoExist(fileNames, userNo);
		if (fileNames.isEmpty() || !flag) // 新增文件及内容
		{
			createXmlDocument(filePath, ptOrderNo, gameAccount, goodsId,
					unitPrice, buyNum, status, totalPrice, date);
		} else
		// 在文件中追加内容
		{
			for (String fileName : fileNames) {
				String[] splitNames = fileName.split(REGEX);
				if (splitNames.length >= 1) {
					if (date.equals(splitNames[0].substring(0, 8))
							&& userNo.equals(splitNames[0].substring(8))) {
						String content = assembleXml(ptOrderNo, gameAccount,
								goodsId, unitPrice, buyNum, status, totalPrice);
						appendXmlFile(filePath, content);
					}
				}
			}
		}
	}

	/**
	 * 生成当前的日期字符串
	 * 
	 * @return
	 */
	public static String createDateString() {
		SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
		String date = format.format(new Date());
		return date;
	}

	/**
	 * 校验相同的日期下,用户id是否存在
	 * 
	 * @param fileNames
	 * @param userNo
	 * @return
	 */
	private static boolean userNoExist(List<String> fileNames, String userNo) {
		boolean result = false;
		String currentDate = createDateString();
		for (String fileName : fileNames) {
			String[] names = fileName.split(REGEX);
			if (names.length >= 1 && StringUtils.isNotEmpty(names[0])) {
				String userid = names[0].substring(8);
				String date = names[0].substring(0, 8);
				if (currentDate.equals(date) && userNo.equals(userid)) {
					result = true;
					break;
				}
			}
		}
		return result;
	}

	/**
	 * 创建xml文件
	 * 
	 * @param filePath
	 * @param ptOrderNo
	 * @param gameAccount
	 * @param supOrderCreateTime
	 * @param goodsId
	 * @param goodsName
	 * @param status
	 * @param amount
	 * @param date
	 */
	private static void createXmlDocument(String filePath, String ptOrderNo,
			String gameAccount, String goodsId, String unitPrice,
			String buyNum, String status, String totalPrice, String date) {
		Document doc = DocumentHelper.createDocument();
		// 创建根元素
		Element root = doc.addElement("bills");
		createSecondElement(root, ptOrderNo, gameAccount, goodsId, unitPrice,
				buyNum, status, totalPrice);
		try {
			String realPath = PropertiesUtil.getValue("bill.project.path");
			String folderName = PropertiesUtil.getValue("bill.folder.name");
			File f = new File(realPath + File.separator + folderName
					+ File.separator + date);
			if (!f.exists()) {
				f.mkdirs();
			}
			File file = new File(filePath);
			OutputStream os = new FileOutputStream(file);
			// xml输出的格式
			OutputFormat format = new OutputFormat();
			format.setEncoding(UTF8);
			// 创建一个专门书写xml的一个书写器
			XMLWriter writer = new XMLWriter(os, format);
			// 把包含数的doc对象写到xml文件中
			writer.write(doc);
			// 关闭资源
			writer.close();
			os.close();
		} catch (FileNotFoundException e) {
			log.error(e);
		} catch (UnsupportedEncodingException e) {
			log.error(e);
		} catch (IOException e) {
			log.error(e);
		}
	}

	/**
	 * @param root
	 * @param ptOrderNo
	 * @param gameAccount
	 * @param supOrderCreateTime
	 * @param goodsId
	 * @param goodsName
	 * @param status
	 * @param amount
	 */
	private static void createSecondElement(Element root, String ptOrderNo,
			String gameAccount, String goodsId, String unitPrice,
			String buyNum, String status, String totalPrice) {
		// 创建一级子标签
		Element bill = root.addElement("orderBill");
		// 创建二级子标签
		Element ptOrderNo2 = bill.addElement("ptOrderNo");
		ptOrderNo2.setText(ptOrderNo);
		Element gameAccount2 = bill.addElement("gameAccount");
		if (StringUtils.isNotEmpty(gameAccount)) {
			gameAccount2.setText(gameAccount);
		}
		Element goodsId2 = bill.addElement("goodsId");
		goodsId2.setText(goodsId);
		Element unitPrice2 = bill.addElement("unitPrice");
		unitPrice2.setText(unitPrice);
		Element buyNum2 = bill.addElement("buyNum");
		buyNum2.setText(buyNum);
		Element status2 = bill.addElement("status");
		if (StringUtils.isNotEmpty(status)) {
			status2.setText(status);
		}
		Element totalPrice2 = bill.addElement("totalPrice");
		totalPrice2.setText(totalPrice);
	}

	/**
	 * 在xml文件末尾追加内容
	 * 
	 * @param fileName
	 * @param content
	 */
	private static void appendXmlFile(String filePath, String content) {
		try {
			// 打开一个随机访问文件流，按读写方式
			RandomAccessFile randomFile = new RandomAccessFile(filePath, "rw");
			byte[] bytes = content.getBytes(UTF8);
			// 文件长度，字节数
			long fileLength = randomFile.length();
			// 将写文件指针移到文件尾前9个字节。
			randomFile.seek(fileLength - 8);
			randomFile.write(bytes);
			randomFile.close();
		} catch (IOException e) {
			log.error(e);
		}
	}

	/**
	 * 拼接追加的xml内容
	 * 
	 * @param ptOrderNo
	 * @param gameAccount
	 * @param goodsId
	 * @param status
	 * @param totalPrice
	 * @return
	 */
	private static String assembleXml(String ptOrderNo, String gameAccount,
			String goodsId, String unitPrice, String buyNum, String status,
			String totalPrice) {
		StringBuilder builder = new StringBuilder();
		builder.append("<orderBill>");
		builder.append("<ptOrderNo>");
		builder.append(ptOrderNo);
		builder.append("</ptOrderNo>");
		builder.append("<gameAccount>");
		builder.append(gameAccount);
		builder.append("</gameAccount>");
		builder.append("<goodsId>");
		builder.append(goodsId);
		builder.append("</goodsId>");
		builder.append("<unitPrice>");
		builder.append(unitPrice);
		builder.append("</unitPrice>");
		builder.append("<buyNum>");
		builder.append(buyNum);
		builder.append("</buyNum>");
		builder.append("<status>");
		builder.append(status);
		builder.append("</status>");
		builder.append("<totalPrice>");
		builder.append(totalPrice);
		builder.append("</totalPrice>");
		builder.append("</orderBill>");
		builder.append("</bills>");
		return builder.toString();
	}

	/**
	 * 读取文件夹下的所有文件,返回当前日期下的文件名集合
	 * 
	 * @param folderPath
	 * @return
	 */
	private static List<String> readFiles(String folderPath) {
		List<String> fileNames = new ArrayList<String>();
		String date = createDateString();
		File file = new File(folderPath);
		if (file.isDirectory()) {
			String[] filelist = file.list();
			for (int i = 0; i < filelist.length; i++) {
				File readfile = new File(folderPath + File.separator
						+ filelist[i]);
				String[] names = readfile.getName().split(REGEX);
				if (names.length >= 1 && StringUtils.isNotEmpty(names[0])) {
					if (readfile.isFile()
							&& date.equals(names[0].substring(0, 8))) {
						fileNames.add(readfile.getName());
					}
				}
			}
		}
		return fileNames;
	}

}
